package common.db.repository;

import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Created by IntelliJ IDEA.
 * User: etran
 * Date: 07-Apr-2009
 * Time: 20:11:50
 */
public class Resourcer
{
	private static final short HISTORY_COUNT = 30;
	private static final String FILE_EXTESION = ".sql";
	private static final String SEPARATOR = "/"; //System.getProperty("file.separator");

	private String repoPath;

	private HashMap<String, String> history;

	/**
	 * Resourcer constructor,
	 * gets sql query from repository files
	 *
	 * @param cls	 class which package contains repository
	 * @param subPath path to sql repository
	 */
	public Resourcer(Class cls, String subPath)
	{
		history = new HashMap<String, String>(HISTORY_COUNT);
		setRepoPath(cls, subPath);
	}

	/**
	 * Resourcer constructor,
	 * gets sql query from repository files
	 *
	 * @param path common path to repository files
	 */
	public Resourcer(String path)
	{
		this(null, path);
	}

	/**
	 * Resourcer constructor,
	 * gets sql query from repository files
	 * (sets repository path to working directory)
	 */
	public Resourcer()
	{
		this(null, null);
	}

	/**
	 * Setter method for path to repository
	 *
	 * @param cls	 class which package contains repository
	 * @param subPath path to sql repository
	 */
	public void setRepoPath(Class cls, String subPath)
	{
		StringBuilder builder = new StringBuilder();
		if (cls != null)
		{
			builder.append(cls.getPackage().getName().replaceAll("\\.", SEPARATOR));
			builder.append(SEPARATOR);
		}
		if (subPath != null)
		{
			builder.append(subPath);
			if (!subPath.endsWith(SEPARATOR))
				builder.append(SEPARATOR);
		}
		synchronized (history)
		{
			history.clear();
			repoPath = builder.toString();
		}
	}

	/**
	 * Getter method for path to repository
	 *
	 * @return common path to sql repository files
	 */
	public String getRepoPath()
	{
		return repoPath;
	}

	/**
	 * Gets sql script
	 *
	 * @param scriptName name of sql script equivalent to repository file (without .sql ext)
	 * @return demanded sql script
	 */
	public String script(String scriptName)
	{
		if (history.containsKey(scriptName))
			return history.get(scriptName);

		InputStream stream = null;
		String sql = null;

		try
		{
			stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(repoPath + scriptName + FILE_EXTESION);

			if(stream == null)
				throw new RuntimeException("No resource: " + repoPath + scriptName + FILE_EXTESION);

			byte[] bytes = new byte[stream.available()];

			stream.read(bytes);
			sql = new String(bytes);

			synchronized (history)
			{
				history.put(scriptName, sql);
			}
		}
		catch (IOException ex)
		{
			ex.printStackTrace();
		}

		try
		{
			if (stream != null)
				stream.close();
		}
		catch (IOException ex)
		{
			ex.printStackTrace();
		}

		return sql;
	}

	/**
	 * Gets sql query
	 *
	 * @param queryName name of sql query equivalent to repository file (without .sql ext)
	 * @return demanded sql query
	 */
	public String query(String queryName)
	{
		return beautify(script(queryName));
	}

	private static String beautify(String sql)
	{
		char[] chs = sql.toCharArray();
		StringBuilder sb = new StringBuilder();
		boolean haveB = false;
		for (int i = 0; i < chs.length; i++)
		{

			if (chs[i] == '\n' || chs[i] == '\r' || chs[i] == '\t')
			{
				haveB = true;
				sb.append(" ");
			}
			else if (chs[i] != ' ')
			{
				if (chs[i] == '?')
				{
					sb.append("? ");
					haveB = true;
				}
				else if (chs[i] == ';')
				{
					sb.append(" ;");
					haveB = true;
				}
				else
				{
					sb.append(chs[i]);
					haveB = false;
				}

			}
			else if (chs[i] == ' ' && !haveB)
			{
				haveB = true;
				sb.append(" ");
			}


		}
		//System.out.println("Dobijeno:-" + sb.toString() + "-");
		return sb.toString();//;sql;
	}
}
